package com.ea.service.impl;


import com.alibaba.fastjson.JSON;
import com.ea.common.constant.RedisKeyConstants;
import com.ea.common.enums.OperationResultCode;
import com.ea.common.exception.ServiceException;
import com.ea.common.filter.AuthFilter;
import com.ea.common.util.RedisUtil;
import com.ea.common.util.TokenUtil;
import com.ea.common.util.TypeConversionToJson;
import com.ea.domain.dto.CartCacheDTO;
import com.ea.domain.dto.CartDTO;
import com.ea.domain.entity.ElectricGoodsSkuInfo;
import com.ea.domain.vo.CartVO;
import com.ea.holder.UserHolderInfo;
import com.ea.mapper.ElectricGoodsSkuInfoMapper;
import com.ea.service.ICartService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author NAME-L
 * @Description 用户购物车方法实现类
 * @className ICartServiceImpl
 * @date 2023-01-05 00:15:51
 */
@Service
public class ICartServiceImpl implements ICartService {
    private static final Logger logger = LoggerFactory.getLogger(ICartServiceImpl.class);

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ElectricGoodsSkuInfoMapper skuInfoMapper;

    @Autowired
    private AuthFilter authFilter;

    @Override
    public void addCart(CartDTO addDTO) {
        if (addDTO == null) {
            throw new ServiceException(OperationResultCode.ADD_CART_ERROR);
        }
        Long userId = addDTO.getUserId();
        Long skuId = addDTO.getSkuId();
        ElectricGoodsSkuInfo skuInfo = skuInfoMapper.selectOneBySkuId(skuId);
        if (skuInfo == null) {
            throw new ServiceException(OperationResultCode.ADD_CART_ERROR);
        }
        // 判断对应货品是否存在购物车中
        boolean existsCart = redisUtil.hHasKey(RedisKeyConstants.USER_CART + userId, skuId.toString());
        boolean flag = false;
        // 存在则增加数量
        if (existsCart) {
            String carJson = (String) redisUtil.hget(RedisKeyConstants.USER_CART + userId, skuId.toString());
            logger.info("carJson:{}", carJson);
            CartCacheDTO cacheDTO = TypeConversionToJson.jsonToEntity(carJson, CartCacheDTO.class);

            logger.info("规格货品:{},已存在购物车中，现有数量：{}，数量增加：{}", skuId, cacheDTO.getAmount() , addDTO.getAmount());
            cacheDTO.setAmount(cacheDTO.getAmount() + addDTO.getAmount());
            String updateCartJson = JSON.toJSONString(cacheDTO);
            flag = redisUtil.hset( RedisKeyConstants.USER_CART + userId, skuId.toString(), updateCartJson);
        }else {
            CartCacheDTO cacheDTO = new CartCacheDTO();
            cacheDTO.setSkuId(skuId);
            cacheDTO.setAmount(addDTO.getAmount());
            String addCartJson = JSON.toJSONString(cacheDTO);
            flag = redisUtil.hset(RedisKeyConstants.USER_CART + userId, skuId.toString(), addCartJson);
        }
        if (!flag) {
            throw new ServiceException(OperationResultCode.ADD_CART_ERROR);
        }
    }

    @Override
    public void updateCart(CartDTO addDTO) {
        Integer amount = addDTO.getAmount();
        if (amount < 0) {
            throw new ServiceException(OperationResultCode.CART_ADD_GOODS_AMOUNT_ERROR);
        }
        // 判断对应货品是否存在购物车中
        boolean existsCart = redisUtil.hHasKey( RedisKeyConstants.USER_CART + addDTO.getUserId(), addDTO.getSkuId().toString());
        boolean flag = false;
        if (existsCart) {
            String carJson = (String) redisUtil.hget( RedisKeyConstants.USER_CART + addDTO.getUserId(), addDTO.getSkuId().toString());
            logger.info("carJson:{}", carJson);
            CartCacheDTO cacheDTO = TypeConversionToJson.jsonToEntity(carJson, CartCacheDTO.class);

            logger.info("规格货品:{},已存在购物车中，现有数量：{}，修改后数量为：{}", addDTO.getSkuId(), amount , addDTO.getAmount());
            cacheDTO.setAmount(amount);
            String updateCartJson = JSON.toJSONString(cacheDTO);
            flag = redisUtil.hset( RedisKeyConstants.USER_CART + addDTO.getUserId(), addDTO.getSkuId().toString(), updateCartJson);
        }
        if (!flag) {
            throw new ServiceException(OperationResultCode.ADD_CART_ERROR);
        }
    }

    @Override
    public void delCartGoods(List<Long> skuIdList) {
        logger.info("删除购物车货品：skuIdList:{}", JSON.toJSONString(skuIdList));
        if (CollectionUtils.isEmpty(skuIdList)) {
            throw new ServiceException(OperationResultCode.PARAMETER_ERROR);
        }
        Long userId = UserHolderInfo.getUserId();
        skuIdList.forEach( skuId -> {
            boolean existsSku = redisUtil.hHasKey( RedisKeyConstants.USER_CART + userId, skuId.toString());
            if (existsSku) {
                redisUtil.hdel( RedisKeyConstants.USER_CART + userId, skuId);
                logger.info("删除货品，skuId:{}" , skuId);
            }
        });
    }

    @Override
    public void delCart(Long userId) {
        logger.info("清空购物车 - userId：{}", userId);
        boolean exists = redisUtil.hasKey( RedisKeyConstants.USER_CART + userId);
        if (exists) {
            redisUtil.del( RedisKeyConstants.USER_CART + userId);
        }

    }

    @Override
    public List<CartVO> showCart(Long userId) {
        boolean exists = redisUtil.hasKey( RedisKeyConstants.USER_CART + userId);
        List<CartCacheDTO> cacheDTOList = new ArrayList<>();
        List<ElectricGoodsSkuInfo> skuInfoList = new ArrayList<>();
        Map<Long, ElectricGoodsSkuInfo> electricGoodsSkuInfoMap = new HashMap<>();
        List<CartVO> cartVOList = new ArrayList<>();
        // 是否存在缓存购物车
        if (exists) {
            Map<Object, Object> cartCacheMap = redisUtil.hmget( RedisKeyConstants.USER_CART + userId);
            if (cartCacheMap == null) {
                return new ArrayList<>();
            }
            for (Map.Entry<Object, Object> entry : cartCacheMap.entrySet()) {
                String goodsInfo = (String) entry.getValue();
                CartCacheDTO cacheDTO = TypeConversionToJson.jsonToEntity(goodsInfo, CartCacheDTO.class);
                cacheDTOList.add(cacheDTO);
            }
            if (CollectionUtils.isNotEmpty(cacheDTOList)) {
                List<Long> skuIdList = cacheDTOList.stream().map(CartCacheDTO::getSkuId).collect(Collectors.toList());
                skuInfoList = skuInfoMapper.selectBySkuIdList(skuIdList);
                electricGoodsSkuInfoMap = skuInfoList.stream().collect(Collectors.toMap(ElectricGoodsSkuInfo::getSkuId, v -> v));
            }
            if (CollectionUtils.isNotEmpty(skuInfoList)) {
                for (CartCacheDTO cacheDTO : cacheDTOList) {
                    if (electricGoodsSkuInfoMap.containsKey(cacheDTO.getSkuId())) {
                        ElectricGoodsSkuInfo skuInfo = electricGoodsSkuInfoMap.get(cacheDTO.getSkuId());
                        CartVO cartVO = new CartVO();
                        cartVO.setSkuId(cacheDTO.getSkuId());
                        cartVO.setSkuName(skuInfo.getSkuName());
                        cartVO.setAmount(cacheDTO.getAmount());
                        cartVO.setImgUrl(null);
                        cartVO.setPrice(skuInfo.getSkuPrice());
                        cartVO.setStatus(skuInfo.getStatus());
                        cartVO.setFlagIds(skuInfo.getFlagIds());
                        cartVOList.add(cartVO);
                    }
                }
            }
        }
        return  cartVOList;

    }
}
